﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Odyssey.ViewModels;
using System.Linq;
using System.Globalization;

namespace Odyssey.Controls.Models
{
    public class TimePickerModel : ViewModelBase
    {
        static TimePickerModel()
        {
            var use24 = CurrentCultureUsesTwentyFourHourClock();
            dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;

            useAmPm = !use24;
            Use24Hours = use24;
            //var pattern = dateTimeFormat.ShortTimePattern;
            //useAmPm = pattern.Contains("tt");
            //Use24Hours = pattern.IndexOf("HH", StringComparison.InvariantCultureIgnoreCase) >= 0;

            amPm = new[] { new DateItem(0, dateTimeFormat.AMDesignator), new DateItem(1, dateTimeFormat.PMDesignator) };
            minutes = Enumerable.Range(0, 60).Select(m => new DateItem(m, m.ToString("D2"))).ToArray();
            hours = Enumerable.Range(Use24Hours ? 0 : 1, Use24Hours ? 24 : 12).Select(h => new DateItem(h, h.ToString("D2"))).ToArray();
        }

        public static bool Use24Hours { get; private set; }
        private static bool useAmPm;

        private DateTime? time;

        private static DateTimeFormatInfo dateTimeFormat;
        private static DateItem[] amPm;
        private static DateItem[] minutes;
        private static DateItem[] hours;

        public bool UseAmPm { get { return useAmPm; } }

        public DateItem[] AmPm { get { return amPm; } }
        public DateItem[] Minutes { get { return minutes; } }
        public DateItem[] Hours { get { return hours; } }

        private DateItem selectedHour;
        private DateItem selectedMinute;
        private DateItem selectedAmPm;

        /// <summary>
        /// Gets or sets the selected time.
        /// </summary>
        public DateTime Time
        {
            get
            {
                if (time == null) Time = DateTime.Now;
                return time.Value;
            }
            set
            {
                if (time != value)
                {
                    time = value;
                    OnPropertyChanged("Date");
                    OnTimeChanged();
                }
            }
        }


        public DateItem SelectedAmPm
        {
            get { return selectedAmPm; }
            set
            {
                if (selectedAmPm != value)
                {
                    selectedAmPm = value;
                    OnPropertyChanged("SelectedAmPm");
                    UpdateTime();
                }
            }
        }


        public DateItem SelectedMinute
        {
            get { return selectedMinute; }
            set
            {
                if (selectedMinute != value)
                {
                    selectedMinute = value;
                    OnPropertyChanged("SelectedMinute");
                    UpdateTime();
                }
            }
        }


        public DateItem SelectedHour
        {
            get { return selectedHour; }
            set
            {
                if (selectedHour != value)
                {
                    selectedHour = value;
                    OnPropertyChanged("SelectedHour");
                    UpdateTime();
                }
            }
        }

        private void UpdateTime()
        {
            if (selectedAmPm != null && selectedHour != null && selectedMinute != null)
            {
                int hour = selectedHour.Value;
                if (!Use24Hours)
                {
                    if (selectedAmPm.Value == 1) hour += 12;
                    if (hour == 12 && selectedAmPm.Value == 0) hour = 0;
                    if (hour == 24) hour = 12;
                }
                Time = new DateTime(1900, 1, 1, hour, selectedMinute.Value, 0);
            }
        }

        /// <summary>
        /// Returns a value indicating whether the current culture uses a 24-hour clock.
        /// </summary>
        /// <returns>True if it uses a 24-hour clock; false otherwise.</returns>
        public static bool CurrentCultureUsesTwentyFourHourClock()
        {
            return !CultureInfo.CurrentCulture.DateTimeFormat.LongTimePattern.Contains("t");
        }


        protected void OnTimeChanged()
        {
            bool use24 = Use24Hours;
            DateTime date = this.time.Value;
            int hour = date.Hour;
            if (!use24)
            {
                if (hour == 0) hour = 12;
                else if (hour > 12) hour -= 12;
                hour--;
            }
            SelectedHour = hours[hour];
            SelectedMinute = minutes[date.Minute];
            SelectedAmPm = amPm[date.Hour >= 12 ? 1 : 0];

            var eh = TimeChanged;
            if (eh != null) eh(this, EventArgs.Empty);
        }

        public event EventHandler TimeChanged;

    }
}
